From ca78f5d3cbdd9478ef1206b2c7f1c9472e28796d Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Thu, 1 Dec 2016 01:38:20 +0100 Subject: [PATCH] gdk: Make gdk_window_begin_draw_frame() take a draw context ... instead of a gl context. This requires some refactoring in the way we mark the shared context as drawing: We now call begin_frame/end_frame() on it and ignore the call on the main context. Unfortunately we need to do this check in all vfuncs, which sucks. But I haven't found a better way. --- gdk/gdkdrawcontext.c | 85 ++++++++++++++- gdk/gdkdrawcontextprivate.h | 13 +++ gdk/gdkdrawingcontext.c | 12 +-- gdk/gdkdrawingcontext.h | 2 +- gdk/gdkglcontext.c | 161 +++++++++-------------------- gdk/gdkglcontextprivate.h | 11 -- gdk/gdkwindow.c | 22 ++-- gdk/gdkwindow.h | 2 +- gdk/mir/gdkmirglcontext.c | 14 ++- gdk/wayland/gdkglcontext-wayland.c | 35 ++++--- gdk/win32/gdkglcontext-win32.c | 16 ++- gdk/x11/gdkglcontext-x11.c | 41 +++++--- gsk/gskglrenderer.c | 10 +- gsk/gskrenderer.c | 31 +----- gsk/gskrendererprivate.h | 2 - 15 files changed, 245 insertions(+), 212 deletions(-) diff --git a/gdk/gdkdrawcontext.c b/gdk/gdkdrawcontext.c index 468de8cfaf..750f8136be 100644 --- a/gdk/gdkdrawcontext.c +++ b/gdk/gdkdrawcontext.c @@ -31,7 +31,7 @@ * @Short_description: Drawing context base class * * #GdkDrawContext is the base object used by contexts implementing different - * rendering methods, such as #GdkGLContext or #GdkVulkanContext. They provide + * rendering methods, such as #GdkDrawContext or #GdkVulkanContext. They provide * shared functionality between those contexts. * * You will always interact with one of those subclasses. @@ -40,6 +40,8 @@ typedef struct _GdkDrawContextPrivate GdkDrawContextPrivate; struct _GdkDrawContextPrivate { GdkWindow *window; + + guint is_drawing : 1; }; enum { @@ -159,6 +161,87 @@ gdk_draw_context_init (GdkDrawContext *self) { } +/*< private > + * gdk_draw_context_is_drawing: + * @context: a #GdkDrawContext + * + * Returns %TRUE if @context is in the process of drawing to its window. In such + * cases, it will have access to the window's backbuffer to render the new frame + * onto it. + * + * Returns: %TRUE if the context is between begin_frame() and end_frame() calls. + * + * Since: 3.90 + */ +gboolean +gdk_draw_context_is_drawing (GdkDrawContext *context) +{ + GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context); + + return priv->is_drawing; +} + +/*< private > + * gdk_draw_context_begin_frame: + * @context: a #GdkDrawContext + * @region: (inout): The clip region that needs to be repainted + * + * Sets up @context and @drawing for a new drawing. + * + * The @context is free to update @region to the size that actually needs to + * be repainted. Contexts that do not support partial blits for example may + * want to invalidate the whole window instead. + * + * The function does not clear the background. Clearing the backgroud is the + * job of the renderer. The contents of the backbuffer are undefined after this + * function call. + * + * Since: 3.90 + */ +void +gdk_draw_context_begin_frame (GdkDrawContext *context, + cairo_region_t *region) +{ + GdkDrawContextPrivate *priv; + + g_return_if_fail (GDK_IS_DRAW_CONTEXT (context)); + g_return_if_fail (region != NULL); + + priv = gdk_draw_context_get_instance_private (context); + priv->is_drawing = TRUE; + + GDK_DRAW_CONTEXT_GET_CLASS (context)->begin_frame (context, region); +} + +/*< private > + * gdk_draw_context_end_frame: + * @context: a #GdkDrawContext + * @painted: The area that has been redrawn this frame + * @damage: The area that we know is actually different from the last frame + * + * Copies the back buffer to the front buffer. + * + * This function may call `glFlush()` implicitly before returning; it + * is not recommended to call `glFlush()` explicitly before calling + * this function. + * + * Since: 3.16 + */ +void +gdk_draw_context_end_frame (GdkDrawContext *context, + cairo_region_t *painted, + cairo_region_t *damage) +{ + GdkDrawContextPrivate *priv; + + g_return_if_fail (GDK_IS_DRAW_CONTEXT (context)); + + GDK_DRAW_CONTEXT_GET_CLASS (context)->end_frame (context, painted, damage); + + priv = gdk_draw_context_get_instance_private (context); + priv->is_drawing = FALSE; +} + /** * gdk_draw_context_get_display: * @context: a #GdkDrawContext diff --git a/gdk/gdkdrawcontextprivate.h b/gdk/gdkdrawcontextprivate.h index da1f25333e..0223787a1d 100644 --- a/gdk/gdkdrawcontextprivate.h +++ b/gdk/gdkdrawcontextprivate.h @@ -39,8 +39,21 @@ struct _GdkDrawContext struct _GdkDrawContextClass { GObjectClass parent_class; + + void (* begin_frame) (GdkDrawContext *context, + cairo_region_t *update_area); + void (* end_frame) (GdkDrawContext *context, + cairo_region_t *painted, + cairo_region_t *damage); }; +gboolean gdk_draw_context_is_drawing (GdkDrawContext *context); +void gdk_draw_context_begin_frame (GdkDrawContext *context, + cairo_region_t *region); +void gdk_draw_context_end_frame (GdkDrawContext *context, + cairo_region_t *painted, + cairo_region_t *damage); + G_END_DECLS #endif /* __GDK__DRAW_CONTEXT_PRIVATE__ */ diff --git a/gdk/gdkdrawingcontext.c b/gdk/gdkdrawingcontext.c index f20c939d78..0ad0c928f0 100644 --- a/gdk/gdkdrawingcontext.c +++ b/gdk/gdkdrawingcontext.c @@ -50,7 +50,7 @@ typedef struct _GdkDrawingContextPrivate GdkDrawingContextPrivate; struct _GdkDrawingContextPrivate { GdkWindow *window; - GdkGLContext *paint_context; + GdkDrawContext *paint_context; cairo_region_t *clip; cairo_t *cr; @@ -191,13 +191,13 @@ gdk_drawing_context_class_init (GdkDrawingContextClass *klass) /** * GdkDrawingContext:paint-context: * - * The #GdkGLContext used to draw or %NULL if Cairo is used. + * The #GdkDrawContext used to draw or %NULL if Cairo is used. * * Since: 3.90 */ obj_property[PROP_PAINT_CONTEXT] = g_param_spec_object ("paint-context", "Paint context", "The context used to draw", - GDK_TYPE_GL_CONTEXT, + GDK_TYPE_DRAW_CONTEXT, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); @@ -244,7 +244,7 @@ gdk_cairo_get_drawing_context (cairo_t *cr) * * Retrieves a Cairo context to be used to draw on the #GdkWindow * that created the #GdkDrawingContext. The @context must have been - * created without a #GdkGLContext for this function to work. If + * created without a #GdkDrawContext for this function to work. If * gdk_drawing_context_get_paint_context() does not return %NULL, * then this function will. * @@ -318,11 +318,11 @@ gdk_drawing_context_get_window (GdkDrawingContext *context) * * Retrieves the paint context used to draw with. * - * Returns: (transfer none): a #GdkGLContext or %NULL + * Returns: (transfer none): a #GdkDrawContext or %NULL * * Since: 3.90 */ -GdkGLContext * +GdkDrawContext * gdk_drawing_context_get_paint_context (GdkDrawingContext *context) { GdkDrawingContextPrivate *priv = gdk_drawing_context_get_instance_private (context); diff --git a/gdk/gdkdrawingcontext.h b/gdk/gdkdrawingcontext.h index 4f9980f90b..f7e044f2ee 100644 --- a/gdk/gdkdrawingcontext.h +++ b/gdk/gdkdrawingcontext.h @@ -39,7 +39,7 @@ GType gdk_drawing_context_get_type (void) G_GNUC_CONST; GDK_AVAILABLE_IN_3_22 GdkWindow * gdk_drawing_context_get_window (GdkDrawingContext *context); GDK_AVAILABLE_IN_3_90 -GdkGLContext* gdk_drawing_context_get_paint_context (GdkDrawingContext *context); +GdkDrawContext* gdk_drawing_context_get_paint_context (GdkDrawingContext *context); GDK_AVAILABLE_IN_3_22 cairo_region_t *gdk_drawing_context_get_clip (GdkDrawingContext *context); diff --git a/gdk/gdkglcontext.c b/gdk/gdkglcontext.c index 4521dd08b8..c12af91ea8 100644 --- a/gdk/gdkglcontext.c +++ b/gdk/gdkglcontext.c @@ -95,7 +95,6 @@ typedef struct { int gl_version; guint realized : 1; - guint is_drawing : 1; guint use_texture_rectangle : 1; guint has_gl_framebuffer_blit : 1; guint has_frame_terminator : 1; @@ -256,13 +255,64 @@ gdk_gl_context_real_realize (GdkGLContext *self, return FALSE; } +static void +gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context, + cairo_region_t *region) +{ + GdkGLContext *context = GDK_GL_CONTEXT (draw_context); + GdkWindow *window; + GdkGLContext *shared; + int ww, wh; + + shared = gdk_gl_context_get_shared_context (context); + if (shared) + { + gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (shared), region); + return; + } + + window = gdk_draw_context_get_window (draw_context); + ww = gdk_window_get_width (window) * gdk_window_get_scale_factor (window); + wh = gdk_window_get_height (window) * gdk_window_get_scale_factor (window); + + gdk_gl_context_make_current (context); + + /* Initial setup */ + glClearColor (0.0f, 0.0f, 0.0f, 0.0f); + glDisable (GL_DEPTH_TEST); + glDisable (GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + glViewport (0, 0, ww, wh); +} + +static void +gdk_gl_context_real_end_frame (GdkDrawContext *draw_context, + cairo_region_t *painted, + cairo_region_t *damage) +{ + GdkGLContext *context = GDK_GL_CONTEXT (draw_context); + GdkGLContext *shared; + + shared = gdk_gl_context_get_shared_context (context); + if (shared) + { + gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (shared), painted, damage); + return; + } +} + static void gdk_gl_context_class_init (GdkGLContextClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass); klass->realize = gdk_gl_context_real_realize; + draw_context_class->begin_frame = gdk_gl_context_real_begin_frame; + draw_context_class->end_frame = gdk_gl_context_real_end_frame; + /** * GdkGLContext:shared-context: * @@ -295,115 +345,6 @@ gdk_gl_context_init (GdkGLContext *self) priv->use_es = -1; } -/*< private > - * gdk_gl_context_is_drawing: - * @context: a #GdkGLContext - * - * Returns %TRUE if @context is in the process of drawing to its window. In such - * cases, it will have access to the window's backbuffer to render the new frame - * onto it. - * - * Returns: %TRUE if the context is between begin_frame() and end_frame() calls. - * - * Since: 3.90 - */ -gboolean -gdk_gl_context_is_drawing (GdkGLContext *context) -{ - GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context); - - return priv->is_drawing; -} - -/*< private > - * gdk_gl_context_begin_frame: - * @context: a #GdkGLContext - * @region: (inout): The clip region that needs to be repainted - * - * Sets up @context and @drawing for a new drawing. - * - * The @context is free to update @region to the size that actually needs to - * be repainted. Contexts that do not support partial blits for example may - * want to invalidate the whole window instead. - * - * The function does not clear the background. Clearing the backgroud is the - * job of the renderer. The contents of the backbuffer are undefined after this - * function call. - * - * Since: 3.90 - */ -void -gdk_gl_context_begin_frame (GdkGLContext *context, - cairo_region_t *region) -{ - GdkGLContextPrivate *priv, *shared_priv; - GdkGLContext *shared; - GdkWindow *window; - int ww, wh; - - g_return_if_fail (GDK_IS_GL_CONTEXT (context)); - g_return_if_fail (region != NULL); - - window = gdk_draw_context_get_window (GDK_DRAW_CONTEXT (context)); - - priv = gdk_gl_context_get_instance_private (context); - priv->is_drawing = TRUE; - - shared = gdk_gl_context_get_shared_context (context); - shared_priv = gdk_gl_context_get_instance_private (shared); - shared_priv->is_drawing = TRUE; - - GDK_GL_CONTEXT_GET_CLASS (context)->begin_frame (context, region); - - ww = gdk_window_get_width (window) * gdk_window_get_scale_factor (window); - wh = gdk_window_get_height (window) * gdk_window_get_scale_factor (window); - - gdk_gl_context_make_current (shared); - - /* Initial setup */ - glClearColor (0.0f, 0.0f, 0.0f, 0.0f); - glDisable (GL_DEPTH_TEST); - glDisable (GL_BLEND); - glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - glViewport (0, 0, ww, wh); - -} - -/*< private > - * gdk_gl_context_end_frame: - * @context: a #GdkGLContext - * @painted: The area that has been redrawn this frame - * @damage: The area that we know is actually different from the last frame - * - * Copies the back buffer to the front buffer. - * - * This function may call `glFlush()` implicitly before returning; it - * is not recommended to call `glFlush()` explicitly before calling - * this function. - * - * Since: 3.16 - */ -void -gdk_gl_context_end_frame (GdkGLContext *context, - cairo_region_t *painted, - cairo_region_t *damage) -{ - GdkGLContextPrivate *priv, *shared_priv; - GdkGLContext *shared; - - g_return_if_fail (GDK_IS_GL_CONTEXT (context)); - - GDK_GL_CONTEXT_GET_CLASS (context)->end_frame (context, painted, damage); - - priv = gdk_gl_context_get_instance_private (context); - priv->is_drawing = FALSE; - - shared = gdk_gl_context_get_shared_context (context); - shared_priv = gdk_gl_context_get_instance_private (shared); - shared_priv->is_drawing = FALSE; -} - GdkGLContextPaintData * gdk_gl_context_get_paint_data (GdkGLContext *context) { diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h index 2f1bb5e6f3..7fc15ca9b4 100644 --- a/gdk/gdkglcontextprivate.h +++ b/gdk/gdkglcontextprivate.h @@ -44,11 +44,6 @@ struct _GdkGLContextClass gboolean (* realize) (GdkGLContext *context, GError **error); - void (* begin_frame) (GdkGLContext *context, - cairo_region_t *update_area); - void (* end_frame) (GdkGLContext *context, - cairo_region_t *painted, - cairo_region_t *damage); gboolean (* texture_from_surface) (GdkGLContext *context, cairo_surface_t *surface, cairo_region_t *region); @@ -90,12 +85,6 @@ gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext gboolean gdk_gl_context_has_framebuffer_blit (GdkGLContext *context); gboolean gdk_gl_context_has_frame_terminator (GdkGLContext *context); gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context); -gboolean gdk_gl_context_is_drawing (GdkGLContext *context); -void gdk_gl_context_begin_frame (GdkGLContext *context, - cairo_region_t *region); -void gdk_gl_context_end_frame (GdkGLContext *context, - cairo_region_t *painted, - cairo_region_t *damage); G_END_DECLS diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c index bf16f03b63..60ac09a8ba 100644 --- a/gdk/gdkwindow.c +++ b/gdk/gdkwindow.c @@ -2816,7 +2816,7 @@ gdk_window_end_paint_internal (GdkWindow *window) */ GdkDrawingContext * gdk_window_begin_draw_frame (GdkWindow *window, - GdkGLContext *gl_context, + GdkDrawContext *draw_context, const cairo_region_t *region) { GdkDrawingContext *context; @@ -2826,10 +2826,10 @@ gdk_window_begin_draw_frame (GdkWindow *window, g_return_val_if_fail (gdk_window_has_native (window), NULL); g_return_val_if_fail (gdk_window_is_toplevel (window), NULL); g_return_val_if_fail (region != NULL, NULL); - if (gl_context != NULL) + if (draw_context != NULL) { - g_return_val_if_fail (GDK_IS_GL_CONTEXT (gl_context), NULL); - g_return_val_if_fail (gdk_gl_context_get_window (gl_context) == window, NULL); + g_return_val_if_fail (GDK_IS_DRAW_CONTEXT (draw_context), NULL); + g_return_val_if_fail (gdk_draw_context_get_window (draw_context) == window, NULL); } if (GDK_WINDOW_DESTROYED (window)) @@ -2845,14 +2845,14 @@ gdk_window_begin_draw_frame (GdkWindow *window, real_region = cairo_region_copy (region); - if (gl_context) - gdk_gl_context_begin_frame (gl_context, real_region); + if (draw_context) + gdk_draw_context_begin_frame (draw_context, real_region); else gdk_window_begin_paint_internal (window, real_region); context = g_object_new (GDK_TYPE_DRAWING_CONTEXT, "window", window, - "paint-context", gl_context, + "paint-context", draw_context, "clip", real_region, NULL); @@ -2883,7 +2883,7 @@ void gdk_window_end_draw_frame (GdkWindow *window, GdkDrawingContext *context) { - GdkGLContext *paint_context; + GdkDrawContext *paint_context; g_return_if_fail (GDK_IS_WINDOW (window)); g_return_if_fail (GDK_IS_DRAWING_CONTEXT (context)); @@ -2903,9 +2903,9 @@ gdk_window_end_draw_frame (GdkWindow *window, paint_context = gdk_drawing_context_get_paint_context (context); if (paint_context) { - gdk_gl_context_end_frame (paint_context, - gdk_drawing_context_get_clip (context), - window->active_update_area); + gdk_draw_context_end_frame (paint_context, + gdk_drawing_context_get_clip (context), + window->active_update_area); } else { diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h index 96d326ca7c..d99dccce02 100644 --- a/gdk/gdkwindow.h +++ b/gdk/gdkwindow.h @@ -628,7 +628,7 @@ void gdk_window_mark_paint_from_clip (GdkWindow *window, GDK_AVAILABLE_IN_3_90 GdkDrawingContext *gdk_window_begin_draw_frame (GdkWindow *window, - GdkGLContext *context, + GdkDrawContext *context, const cairo_region_t *region); GDK_AVAILABLE_IN_3_22 void gdk_window_end_draw_frame (GdkWindow *window, diff --git a/gdk/mir/gdkmirglcontext.c b/gdk/mir/gdkmirglcontext.c index a4c00c211f..ae98c5282c 100644 --- a/gdk/mir/gdkmirglcontext.c +++ b/gdk/mir/gdkmirglcontext.c @@ -98,12 +98,17 @@ gdk_mir_gl_context_realize (GdkGLContext *context, } static void -gdk_mir_gl_context_begin_frame (GdkGLContext *context, +gdk_mir_gl_context_begin_frame (GdkDrawContext *draw_context, cairo_region_t *update_area) { - GdkDisplay *display = gdk_gl_context_get_display (window); + GdkGLContext *context = GDK_GL_CONTEXT (draw_context); + GdkDisplay *display = gdk_draw_context_get_display (draw_context); GdkWindow *window; + GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->begin_frame (draw_context, update_area); + if (gdk_gl_context_get_shared_context (context)) + return; + if (_gdk_mir_display_have_egl_swap_buffers_with_damage (display)) return; @@ -121,12 +126,17 @@ gdk_mir_gl_context_end_frame (GdkGLContext *context, cairo_region_t *painted, cairo_region_t *damage) { + GdkGLContext *context = GDK_GL_CONTEXT (draw_context); GdkWindow *window = gdk_gl_context_get_window (context); GdkDisplay *display = gdk_window_get_display (window); GdkMirGLContext *context_mir = GDK_MIR_GL_CONTEXT (context); EGLDisplay egl_display = _gdk_mir_display_get_egl_display (display); EGLSurface egl_surface; + GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->end_frame (draw_context, painted, damage); + if (gdk_gl_context_get_shared_context (context)) + return; + gdk_gl_context_make_current (context); egl_surface = _gdk_mir_window_get_egl_surface (window, diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c index a57e1e4e17..42ba97c9e0 100644 --- a/gdk/wayland/gdkglcontext-wayland.c +++ b/gdk/wayland/gdkglcontext-wayland.c @@ -35,14 +35,19 @@ G_DEFINE_TYPE (GdkWaylandGLContext, gdk_wayland_gl_context, GDK_TYPE_GL_CONTEXT) -static void gdk_x11_gl_context_dispose (GObject *gobject); +static void gdk_wayland_gl_context_dispose (GObject *gobject); static void -gdk_wayland_gl_context_begin_frame (GdkGLContext *context, +gdk_wayland_gl_context_begin_frame (GdkDrawContext *draw_context, cairo_region_t *update_area) { + GdkGLContext *context = GDK_GL_CONTEXT (draw_context); GdkWindow *window; + GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->begin_frame (draw_context, update_area); + if (gdk_gl_context_get_shared_context (context)) + return; + /* If nothing else is known, repaint everything so that the back buffer is fully up-to-date for the swapbuffer */ window = gdk_gl_context_get_window (context); @@ -171,21 +176,25 @@ gdk_wayland_gl_context_realize (GdkGLContext *context, } static void -gdk_wayland_gl_context_end_frame (GdkGLContext *context, +gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context, cairo_region_t *painted, cairo_region_t *damage) { + GdkGLContext *context = GDK_GL_CONTEXT (draw_context); GdkWindow *window = gdk_gl_context_get_window (context); GdkDisplay *display = gdk_window_get_display (window); GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display); - GdkGLContext *shared = gdk_gl_context_get_shared_context (context); - GdkWaylandGLContext *shared_wayland = GDK_WAYLAND_GL_CONTEXT (shared); + GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context); EGLSurface egl_surface; - gdk_gl_context_make_current (shared); + GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted, damage); + if (gdk_gl_context_get_shared_context (context)) + return; + + gdk_gl_context_make_current (context); egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window, - shared_wayland->egl_config); + context_wayland->egl_config); if (display_wayland->have_egl_swap_buffers_with_damage) { @@ -213,13 +222,15 @@ static void gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass); GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass); - gobject_class->dispose = gdk_x11_gl_context_dispose; + gobject_class->dispose = gdk_wayland_gl_context_dispose; + + draw_context_class->begin_frame = gdk_wayland_gl_context_begin_frame; + draw_context_class->end_frame = gdk_wayland_gl_context_end_frame; context_class->realize = gdk_wayland_gl_context_realize; - context_class->begin_frame = gdk_wayland_gl_context_begin_frame; - context_class->end_frame = gdk_wayland_gl_context_end_frame; } static void @@ -419,7 +430,7 @@ gdk_wayland_window_create_gl_context (GdkWindow *window, } static void -gdk_x11_gl_context_dispose (GObject *gobject) +gdk_wayland_gl_context_dispose (GObject *gobject) { GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (gobject); @@ -463,7 +474,7 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay *display, context_wayland = GDK_WAYLAND_GL_CONTEXT (context); window = gdk_gl_context_get_window (context); - if (context_wayland->is_attached || gdk_gl_context_is_drawing (context)) + if (context_wayland->is_attached || gdk_draw_context_is_drawing (GDK_DRAW_CONTEXT (context))) egl_surface = gdk_wayland_window_get_egl_surface (window->impl_window, context_wayland->egl_config); else { diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c index 12adf73d20..477886bfdf 100644 --- a/gdk/win32/gdkglcontext-win32.c +++ b/gdk/win32/gdkglcontext-win32.c @@ -101,15 +101,20 @@ gdk_gl_blit_region (GdkWindow *window, cairo_region_t *region) } static void -gdk_win32_gl_context_end_frame (GdkGLContext *context, +gdk_win32_gl_context_end_frame (GdkDrawContext *draw_context, cairo_region_t *painted, cairo_region_t *damage) { + GdkGLContext *context = GDK_GL_CONTEXT (draw_context); GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context); GdkWindow *window = gdk_gl_context_get_window (context); GdkWin32Display *display = (GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context))); - gboolean can_wait = display->hasWglOMLSyncControl; + + GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->end_frame (draw_context, painted, damage); + if (gdk_gl_context_get_shared_context (context)) + return; + gdk_gl_context_make_current (context); if (context_win32->do_frame_sync) @@ -156,11 +161,16 @@ gdk_win32_gl_context_end_frame (GdkGLContext *context, } static void -gdk_win32_gl_context_begin_frame (GdkGLContext *context, +gdk_win32_gl_context_begin_frame (GdkDrawContext *draw_context, cairo_region_t *update_area) { + GdkGLContext *context = GDK_GL_CONTEXT (draw_context); GdkWindow *window; + GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->begin_frame (draw_context, update_area); + if (gdk_gl_context_get_shared_context (context)) + return; + if (gdk_gl_context_has_framebuffer_blit (context)) return; diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c index 66651890a2..5662bc544b 100644 --- a/gdk/x11/gdkglcontext-x11.c +++ b/gdk/x11/gdkglcontext-x11.c @@ -120,11 +120,16 @@ maybe_wait_for_vblank (GdkDisplay *display, } static void -gdk_x11_gl_context_begin_frame (GdkGLContext *context, +gdk_x11_gl_context_begin_frame (GdkDrawContext *draw_context, cairo_region_t *update_area) { + GdkGLContext *context = GDK_GL_CONTEXT (draw_context); GdkWindow *window; + GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->begin_frame (draw_context, update_area); + if (gdk_gl_context_get_shared_context (context)) + return; + if (gdk_gl_context_has_framebuffer_blit (context)) return; @@ -157,12 +162,12 @@ gdk_gl_blit_region (GdkWindow *window, cairo_region_t *region) } static void -gdk_x11_gl_context_end_frame (GdkGLContext *context, +gdk_x11_gl_context_end_frame (GdkDrawContext *draw_context, cairo_region_t *painted, cairo_region_t *damage) { - GdkGLContext *shared = gdk_gl_context_get_shared_context (context); - GdkX11GLContext *shared_x11 = GDK_X11_GL_CONTEXT (shared); + GdkGLContext *context = GDK_GL_CONTEXT (draw_context); + GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context); GdkWindow *window = gdk_gl_context_get_window (context); GdkDisplay *display = gdk_gl_context_get_display (context); Display *dpy = gdk_x11_display_get_xdisplay (display); @@ -171,17 +176,21 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context, DrawableInfo *info; GLXDrawable drawable; - gdk_gl_context_make_current (shared); + GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_parent_class)->end_frame (draw_context, painted, damage); + if (gdk_gl_context_get_shared_context (context)) + return; + + gdk_gl_context_make_current (context); info = get_glx_drawable_info (window); - drawable = shared_x11->attached_drawable; + drawable = context_x11->attached_drawable; GDK_NOTE (OPENGL, g_message ("Flushing GLX buffers for drawable %lu (window: %lu), frame sync: %s", (unsigned long) drawable, (unsigned long) gdk_x11_window_get_xid (window), - shared_x11->do_frame_sync ? "yes" : "no")); + context_x11->do_frame_sync ? "yes" : "no")); /* if we are going to wait for the vertical refresh manually * we need to flush pending redraws, and we also need to wait @@ -191,7 +200,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context, * GLX_SGI_swap_control, and we ask the driver to do the right * thing. */ - if (shared_x11->do_frame_sync) + if (context_x11->do_frame_sync) { guint32 end_frame_counter = 0; gboolean has_counter = display_x11->has_glx_video_sync; @@ -200,7 +209,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context, if (display_x11->has_glx_video_sync) glXGetVideoSyncSGI (&end_frame_counter); - if (shared_x11->do_frame_sync && !display_x11->has_glx_swap_interval) + if (context_x11->do_frame_sync && !display_x11->has_glx_swap_interval) { glFinish (); @@ -221,7 +230,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context, { glXSwapBuffers (dpy, drawable); } - else if (gdk_gl_context_has_framebuffer_blit (shared)) + else if (gdk_gl_context_has_framebuffer_blit (context)) { glDrawBuffer(GL_FRONT); glReadBuffer(GL_BACK); @@ -229,7 +238,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context, glDrawBuffer(GL_BACK); glFlush(); - if (gdk_gl_context_has_frame_terminator (shared)) + if (gdk_gl_context_has_frame_terminator (context)) glFrameTerminatorGREMEDY (); } else @@ -238,7 +247,7 @@ gdk_x11_gl_context_end_frame (GdkGLContext *context, glXSwapBuffers (dpy, drawable); } - if (shared_x11->do_frame_sync && info != NULL && display_x11->has_glx_video_sync) + if (context_x11->do_frame_sync && info != NULL && display_x11->has_glx_video_sync) glXGetVideoSyncSGI (&info->last_frame_counter); } @@ -774,13 +783,15 @@ static void gdk_x11_gl_context_class_init (GdkX11GLContextClass *klass) { GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass); + GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); context_class->realize = gdk_x11_gl_context_realize; - context_class->begin_frame = gdk_x11_gl_context_begin_frame; - context_class->end_frame = gdk_x11_gl_context_end_frame; context_class->texture_from_surface = gdk_x11_gl_context_texture_from_surface; + draw_context_class->begin_frame = gdk_x11_gl_context_begin_frame; + draw_context_class->end_frame = gdk_x11_gl_context_end_frame; + gobject_class->dispose = gdk_x11_gl_context_dispose; } @@ -1259,7 +1270,7 @@ gdk_x11_display_make_gl_context_current (GdkDisplay *display, return FALSE; } - if (context_x11->is_attached || gdk_gl_context_is_drawing (context)) + if (context_x11->is_attached || gdk_draw_context_is_drawing (GDK_DRAW_CONTEXT (context))) drawable = context_x11->attached_drawable; else drawable = context_x11->unattached_drawable; diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c index e021b358fa..5d0bb12c63 100644 --- a/gsk/gskglrenderer.c +++ b/gsk/gskglrenderer.c @@ -292,8 +292,6 @@ gsk_gl_renderer_realize (GskRenderer *renderer, if (!gsk_gl_renderer_create_programs (self, error)) return FALSE; - gsk_renderer_set_gl_context (renderer, self->gl_context); - return TRUE; } @@ -320,8 +318,6 @@ gsk_gl_renderer_unrealize (GskRenderer *renderer) if (self->gl_context == gdk_gl_context_get_current ()) gdk_gl_context_clear_current (); - - gsk_renderer_set_gl_context (renderer, NULL); } static GdkDrawingContext * @@ -341,9 +337,9 @@ gsk_gl_renderer_begin_draw_frame (GskRenderer *renderer, gdk_window_get_height (window) }); - result = gdk_window_begin_draw_frame (window, - self->gl_context, - region); + return gdk_window_begin_draw_frame (window, + GDK_DRAW_CONTEXT (self->gl_context), + region); cairo_region_destroy (whole_window); diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index fc563784fd..d4ed4e2a7d 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -67,7 +67,6 @@ typedef struct GskScalingFilter mag_filter; GdkWindow *window; - GdkGLContext *gl_context; GdkDrawingContext *drawing_context; GskRenderNode *root_node; GdkDisplay *display; @@ -119,7 +118,7 @@ gsk_renderer_real_begin_draw_frame (GskRenderer *self, GskRendererPrivate *priv = gsk_renderer_get_instance_private (self); return gdk_window_begin_draw_frame (priv->window, - priv->gl_context, + NULL, region); } @@ -604,8 +603,6 @@ gsk_renderer_unrealize (GskRenderer *renderer) GSK_RENDERER_GET_CLASS (renderer)->unrealize (renderer); - g_warn_if_fail (priv->gl_context == NULL); - priv->is_realized = FALSE; } @@ -847,32 +844,6 @@ gsk_renderer_get_cairo_context (GskRenderer *renderer) return priv->cairo_context; } -void -gsk_renderer_set_gl_context (GskRenderer *renderer, - GdkGLContext *context) -{ - GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer); - - g_set_object (&priv->gl_context, context); -} - -/** - * gsk_renderer_get_gl_context: - * @renderer: a #GskRenderer - * - * Returns the GL context used by @renderer. The only use for using this - * function is to pass the result to gdk_window_begin_draw_frame(). - * - * Returns: The GL context to use for creating drawing contexts - **/ -GdkGLContext * -gsk_renderer_get_gl_context (GskRenderer *renderer) -{ - GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer); - - return priv->gl_context; -} - GdkDrawingContext * gsk_renderer_begin_draw_frame (GskRenderer *renderer, const cairo_region_t *region) diff --git a/gsk/gskrendererprivate.h b/gsk/gskrendererprivate.h index 2ac3c92599..027229c693 100644 --- a/gsk/gskrendererprivate.h +++ b/gsk/gskrendererprivate.h @@ -57,8 +57,6 @@ struct _GskRendererClass gboolean gsk_renderer_is_realized (GskRenderer *renderer); -void gsk_renderer_set_gl_context (GskRenderer *renderer, - GdkGLContext *context); GskRenderNode * gsk_renderer_get_root_node (GskRenderer *renderer); GdkDrawingContext * gsk_renderer_get_drawing_context (GskRenderer *renderer); cairo_t * gsk_renderer_get_cairo_context (GskRenderer *renderer); -- 2.30.2